package net.dopan.pigframe.config.security;

import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import net.dopan.pigframe.core.bean.config.FilterIgnorePropertiesConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

/**
 * @author: 刘宽
 */
@Slf4j
@Order(SecurityProperties.DEFAULT_FILTER_ORDER - 1)
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry
                = http.csrf().disable().authorizeRequests();
        registry.antMatchers(HttpMethod.OPTIONS).permitAll();
        log.info("AuthIgnoreUrls: {}", filterIgnorePropertiesConfig.getUrls());
        filterIgnorePropertiesConfig.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
        registry.anyRequest().authenticated().and().httpBasic();
    }

    @Autowired
    private RefreshScope refreshScope;
    /**
     * apollo更新刷新filterIgnorePropertiesConfig
     * @param changeEvent
     */
    @ApolloConfigChangeListener
    public void onChange(ConfigChangeEvent changeEvent) {
        boolean ignoreCacheKeysChanged = false;
        for (String changedKey : changeEvent.changedKeys()) {
            if (changedKey.startsWith("ignore")) {
                ignoreCacheKeysChanged = true;
                break;
            }
        }
        if (!ignoreCacheKeysChanged) {
            return;
        }
        log.info("AuthIgnoreUrls before refresh {}", filterIgnorePropertiesConfig.getUrls());
        refreshScope.refresh("filterIgnorePropertiesConfig");
        log.info("AuthIgnoreUrls after refresh {}", filterIgnorePropertiesConfig.getUrls());
    }
}
